/*
 * @(#)SearchTableModel.java 0.0.1-SNAPSHOT
 *
 * Copyright Group B
 */
package grupb.upf.gui;

import grupb.upf.XMLObjects.New;
import grupb.upf.XMLObjects.Photo;
import grupb.upf.XMLObjects.Video;
import grupb.upf.ms.DescriptionContent;
import java.util.LinkedList;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;

/**
 * <p>This is the model of the table of results.</p>
 *
 * @version    0.0.1-SNAPSHOT
 * @author     Group B
 */
public final class SearchTableModel implements javax.swing.table.TableModel {

    /**
     * List of subscribers. It is necessary to implement the class TableModel.
     */
    private LinkedList subscribers = new LinkedList();
    /**
     * List of listeners. It is necessary to implement the class TableModel.
     */
    private LinkedList listeners = new LinkedList();
    /**
     * The information, in this case a list of DescriptionContents
     */
    private LinkedList data = new LinkedList();

    /**
     * Method to get the number of rows.
     * @return the number of rows
     */
    @Override
    public int getRowCount() {
        return data.size();
    }

    /**
     * Method to get the number of columns.
     * @return The number of columns
     */
    @Override
    public int getColumnCount() {
        return 4;
    }

    /**
     * Method to get the name of a column.
     * @param columnIndex the index of the column
     * @return the name
     */
    @Override
    public String getColumnName(final int columnIndex) {
        switch (columnIndex) {
            case 0:
                return "Title";
            case 1:
                return "Type";
            case 2:
                return "Owner";
            case 3:
                return "Tags";
            default:
                return null;
        }
    }

    /**
     * Method to get the class of a column.
     * @param columnIndex the index of the column
     * @return the class of a column
     */
    @Override
    public Class<?> getColumnClass(final int columnIndex) {
        return String.class;
    }

    /**
     * Method to know if a cell is editable.
     * @param rowIndex the index of the row
     * @param columnIndex the index of the column
     * @return always false
     */
    @Override
    public boolean isCellEditable(final int rowIndex, final int columnIndex) {
        return false;
    }

    /**
     * Method to get a value in a concrete row, the Column doesn't matter.
     * @param rowIndex the index of the row
     * @param columnIndex it doesn't matter
     * @return the value of the object DescriptionContent.
     */
    @Override
    public Object getValueAt(final int rowIndex, final int columnIndex) {
        if (data != null) {
            final DescriptionContent dc = (DescriptionContent) data.get(rowIndex);
            String title = "";
            String type = "";
            String owner = (String) dc.getProperty("from");
            String tags = "";
            if (dc.getProperty("properties") instanceof Photo) {
                type = "Photo";
                Photo p = (Photo) dc.getProperty("properties");
                title = p.getMetadataDC().getContentProperty("dc.title");
                tags = p.getTags().getTagsAsString();
            } else if (dc.getProperty("properties") instanceof Video) {
                type = "Video";
                Video v = (Video) dc.getProperty("properties");
                title = v.getMetadataDC().getContentProperty("dc.title");
                tags = v.getTags().getTagsAsString();
            } else if (dc.getProperty("properties") instanceof New) {
                type = "New";
                New nw = (New) dc.getProperty("properties");
                title = nw.getTitle();
                tags = nw.getTags().getTagsAsString();
            }
            switch (columnIndex) {
                case 0:
                    return title;
                case 1:
                    return type;
                case 2:
                    return owner;
                case 3:
                    return tags;
                default:
                    return null;
            }
        }
        return null;
    }

    /**
     * Method to delete a Result.
     * @param row
     */
    public void deleteResult(final int row) {
        data.remove(row);
        final TableModelEvent event = new TableModelEvent(this, row, row,
                TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE);
        notice(event);
    }

    /**
     * Method to add a result.
     * @param dc the DescriptionContent of the result to add
     */
    public void addResult(final DescriptionContent dc) {
        data.add(dc);
        final TableModelEvent event = new TableModelEvent(this,
                this.getRowCount() - 1, this.getRowCount() - 1,
                TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT);
        notice(event);
    }

    /**
     * Method to get a concrete result.
     * @param row the row
     * @return the DescriptionContent
     */
    public DescriptionContent getResult(final int row) {
        return (DescriptionContent) data.get(row);
    }

    /**
     * Method to set a value at a concrete position.
     * @param aValue the value
     * @param rowIndex the index of the row
     * @param columnIndex the index of the column
     */
    @Override
    public void setValueAt(final Object aValue, final int rowIndex,
            final int columnIndex) {
    }

    /**
     * Method to add a listener.
     * @param l the listener to be added
     */
    @Override
    public void addTableModelListener(final TableModelListener l) {
        subscribers.add(l);
    }

    /**
     * Method to remove a listener or subscriber.
     * @param l the listener
     */
    @Override
    public void removeTableModelListener(final TableModelListener l) {
        subscribers.remove(l);
    }

    /**
     * Method to notice to subscribers a change.
     * @param event the event
     */
    private void notice(final TableModelEvent event) {
        int i;
        for (i = 0; i < listeners.size(); i++) {
            ((TableModelListener) listeners.get(i)).tableChanged(event);
        }
    }
}
